package ghttp

import (
	"io"
	"net/http"
	"strings"
	"time"
)

const (
	DefaultTimeout      = 5 // 默认超时时间，单位秒
	MaxIdleConns        = 20
	MaxIdleConnsPerHost = 10
)

type Client struct {
	Client  *http.Client
	Timeout int // 超时时间，单位秒
}

var DefaultClient *Client

func init() {
	DefaultClient = NewClient(MaxIdleConns, MaxIdleConnsPerHost)
}

func NewClient(maxIdleConns, maxIdleConnsPerHost int) *Client {
	c := Client{}
	c.Client = &http.Client{
		Transport: &http.Transport{
			MaxIdleConns:        maxIdleConns,
			MaxIdleConnsPerHost: maxIdleConnsPerHost,
		}}
	return &c
}

func DoGet(url string) (string, error) {
	return DoGetWithHeader(url, nil)
}

func DoGetWithHeader(url string, header map[string]string) (string, error) {
	return DefaultClient.DoRequestWithHeader(url, http.MethodGet, "", header)
}

func DoPost(url, body string) (string, error) {
	return DoPostWithHeader(url, body, nil)
}

func DoPostWithHeader(url, body string, header map[string]string) (string, error) {
	return DefaultClient.DoRequestWithHeader(url, http.MethodPost, body, header)
}

// DoRequestWithHeader
// method 支持GET， POST等方式，应该传常量，而不是直接传字符串，参考http.MethodGet
// timeout 超时时间，单位秒
func (p *Client) DoRequestWithHeader(url, method, body string, header map[string]string) (string, error) {
	var bodyReader io.Reader
	if len(body) > 0 {
		bodyReader = strings.NewReader(body)
	}
	req, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		return "", err
	}

	if header != nil && len(header) > 0 {
		for k, v := range header {
			req.Header.Set(k, v)
		}
	}

	p.Client.Timeout = time.Second * time.Duration(p.Timeout)

	resp, err := DefaultClient.Client.Do(req)
	if err != nil {
		return "", err
	}

	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(data), nil
}
